
/**
 * Copyright 2009 cestum.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package org.waveprotocol.wave.model.document.operation.algorithm.transformer
{
import org.goverla.collections.ArrayList;
import org.waveprotocol.wave.model.document.operation.AnnotationBoundaryMap;
import org.waveprotocol.wave.model.document.operation.algorithm.ValueUpdate;
import org.waveprotocol.wave.model.document.operation.impl.AnnotationBoundaryMapImpl;

public final class ClientAnnotationTracker extends AnnotationTracker {
	var serverAnnotationProcessor:AnnotationProcessor;
	var clientAnnotationProcessor:AnnotationProcessor;
	var serverAnnotationTracker:AnnotationTracker;
	
	public function ClientAnnotationTracker(
		clientProcessor:AnnotationProcessor, 
		serverProcessor: AnnotationProcessor,
		serverTracker: AnnotationTracker) {
		super(clientProcessor);
		this.clientAnnotationProcessor = clientProcessor;
		this.serverAnnotationProcessor = serverProcessor;
		this.serverAnnotationTracker = serverTracker;
	}
	
	override function processUpdate(map:AnnotationBoundaryMap):void {
		var clientEndKeys:ArrayList= new ArrayList();
		var clientChangeKeys:ArrayList= new ArrayList();
		var clientChangeOldValues:ArrayList= new ArrayList();
		var clientChangeNewValues:ArrayList= new ArrayList();
		var serverEndKeys:ArrayList= new ArrayList();
		var serverChangeKeys:ArrayList= new ArrayList();
		var serverChangeOldValues:ArrayList= new ArrayList();
		var serverChangeNewValues:ArrayList= new ArrayList();
		for (var i:int= 0; i < map.endSize(); ++i) {
			var key:String= map.getEndKey(i);
			var serverValues:ValueUpdate= ValueUpdate(serverAnnotationTracker.active.getItem(key));
			clientEndKeys.addItem(key);
			if (serverValues != null) {
				serverChangeKeys.addItem(key);
				serverChangeOldValues.addItem(serverValues.oldValue);
				serverChangeNewValues.addItem(serverValues.newValue);
			}
		}
		for (var i:int= 0; i < map.changeSize(); ++i) {
			var key:String= map.getChangeKey(i);
			var oldValue:String= map.getOldValue(i);
			var newValue:String= map.getNewValue(i);
			var serverValues:ValueUpdate= ValueUpdate(serverAnnotationTracker.active.getItem(key));
			clientChangeKeys.addItem(key);
			clientChangeNewValues.addItem(newValue);
			if (serverValues != null) {
				clientChangeOldValues.addItem(serverValues.newValue);
				serverEndKeys.addItem(key);
			} else {
				clientChangeOldValues.addItem(oldValue);
			}
		}
		clientAnnotationProcessor.process(new AnnotationBoundaryMapImpl(
			clientEndKeys.toArray(),
			clientChangeKeys.toArray(),
			clientChangeOldValues.toArray(),
			clientChangeNewValues.toArray()));
		serverAnnotationProcessor.process(new AnnotationBoundaryMapImpl(
			serverEndKeys.toArray(),
			serverChangeKeys.toArray(),
			serverChangeOldValues.toArray(),
			serverChangeNewValues.toArray()));
	}
	
	
	override function opposingTracker():AnnotationTracker {
		return serverAnnotationTracker;
	}
	
}
}